<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>

<script type="text/javascript">

(function(){

//****************************************************************************
// API

this.module /* module_v3 */ = function(){
	var args = arguments;
	var namespace = args[0];
	var expected = 2;
	
	if (typeof namespace != "string")
	{
		namespace = "";
		expected = 1;
	}

	if(args.length == expected)
		var initialize, Scope = args[expected-1];
	
	else if(args.length == expected+1)
		var initialize = args[expected-1], Scope = args[expected];
	
	else
		return undefined;

	var p = namespace.split("::");
	if (!namespace || p.length == 1)
	{
		var isClass = false;
		var Module = function(){};
	}
	else
	{
		var isClass = true;
		var Module = initialize = initialize || function(){};
		if (namespace)
		{
			var inherit = p[0];
			namespace = p[1];
	    	if (inherit && inherit != "Object")
	        	Module.prototype = new (getNamespace(inherit));
		}        	
	}

	Scope.prototype = new Module;
	extend(Scope, {
		protect: function(obj){ extend(Scope, obj); },
		publish: function(obj){ publish(Scope, Module, obj); }
	});

	if (isClass)
	{
		var scope = new Scope();
		return namespace ? createNamespace(namespace, Module) : Module;
	}
	else
	{
		var api = new Module();
		var scope = new Scope();
		return namespace ? createNamespace(namespace, api) : api;
	}
}


function publish(Scope, Module, obj)
{
	var _ = Scope.prototype, m = Module.prototype, f;
    for (var n in obj)
    {
        f = obj[n];
        if (typeof f == "function")
        	m[n] =  function() { return f.apply(_, arguments); }
        else
        	m[n] = f;
    }
        
    return m;
};

/*
this.module_v2 = function(){
	var args = arguments;
	var namespace = args[0];
	
	if (typeof namespace != "string") return undefined;

	if(args.length == 2)
		var initialize, Scope = args[1];
	
	else if(args.length == 3)
		var initialize = args[1], Scope = args[2];
	
	else
		return undefined;
	
	function Module(){};
	
	Scope.prototype = new Module;
	extend(Scope, {
		protect: function(obj){ extend(Scope, obj); },
		extend: function(obj){ publish(Scope.prototype, Module.prototype, obj); }
	});

	var api = new Module();
	var scope = new Scope();

	return api;
}

this.module_v1 = function(namespace, options){

	if (typeof namespace != "string") return undefined;

	var initialize = options.initialize;
	var external = options.external; 
	var internal = options.internal;

	var p = namespace.split("::");
	if (p.length == 1)
	{
		var isClass = false;
    	var __scope__ = {};
    	
		createNamespace(namespace, __scope__);
	}
	else if (p.length == 2)
	{
		namespace = p[1]; 
		initialize = initialize || function(){};
    	if (p[0] != "Object")
    	{
        	var base = getNamespace(p[0]);
    		initialize.prototype = new base;
    	}        	

		var isClass = true;
    	var __scope__ = initialize.prototype;
    	__scope__.extend = classExtend;

    	createNamespace(namespace, initialize);
	}
	
	if (!modules[namespace])
	{
		var me = (external+"").match(reFn);
		var mi = (internal+"").match(reFn);

		if (isClass)
			var init = "";
		else
		{
			var mt = (initialize+"").match(reFn);
			var init = "(function(){" + mt[2] + "}).apply(__scope__)";
		}
		
		var s = [
		    	"(function(){",
		    	mi[2],
		    	"(function(){",
		    	me[2],
		    	init,
		    	"}).apply(__scope__)}).apply(__scope__);"
			].join("");

		eval(s);
			
		modules[namespace] = {
			scope: __scope__,
			external: external,
			internal: internal
		};
	}

	if(isClass)
		return initialize;
	else
		return __scope__;
}
/**/
//****************************************************************************

var modules = {};
var reFn = /(function \w*\(.*\)\s*\{)([\s\S]*)\}/;

function createNamespace(ns, source) {
	if (!ns) return false;
	
	var n = ns.split(".");
	var target = window, o;
	
	for (var i = 0, l = n.length-1, ni; (ni = n[i]) && (i < l); i++)
		target = (o = target[ni]) ? o : target[ni] = {};
	
	target = target[ni] = source || {};
	
	return target;
};

function getNamespace(ns) {
	if (!ns) return false;
	
	var n = ns.split(".");
	var target = window;
	
	for (var i = 0, l = n.length-1, ni; (ni = n[i]) && (i < l); i++)
		if (o = target[ni])
			target = o
		else
			return undefined;
	
	return target[ni];
};

function classExtend(r)
{
    for (var n in r)
        this.prototype[n] = r[n];
        
    return this;
};


this.extend = function(l, r)
{
    var obj = l.prototype || l;
    for (var n in r)
        obj[n] = r[n];
        
    return obj;
};

this.inherit = function(l, r)
{
    if (!r)
    {
        r = l;
        var newOb = {};
    } 
    if (l.prototype)
        var newOb = new l;
    else
    {
        var newOb = {};
        for (var n in l)
            newOb[n] = l[n];
    }
        
    for (var n in r)
        newOb[n] = r[n];
    return newOb;
};




//****************************************************************************

})(window);

module("MOD", function(){

this.publish({
	show: function(){
		return "I can read " + this.inner() +
			" and " + hidden + " stuff.";
	}
});

var hidden = "hidden";

this.protect({
	inner: function(){
		return "protected";
	}
});

});
/**/


</script>

</head>
<body>

</body>
</html>